/**
 ******************************************************************************
 * @file    zb32l03x_hal_def.h
 * @author  MCU Software Team
 * @Version V1.0.0
 * @Date    2022/01/19
 * @brief   This file contains HAL common defines, enumeration, macros and
 *          structures definitions.
 ******************************************************************************
 */


#ifndef __ZB32L03x_HAL_DEF
#define __ZB32L03x_HAL_DEF

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>
#include "zb32l03x.h"


/**
 * @brief  HAL Status structures definition
 */
typedef enum
{
    HAL_OK              = 0x00U,
    HAL_ERROR           = 0x01U,
    HAL_BUSY            = 0x02U,
    HAL_TIMEOUT         = 0x03U,
    HAL_RCC_OUT_RANGE   = 0x04U,
} HAL_StatusTypeDef;

/**
 * @brief  HAL Lock structures definition
 */
typedef enum
{
    HAL_UNLOCKED = 0x00U,
    HAL_LOCKED   = 0x01U
} HAL_LockTypeDef;

typedef enum
{
    RESET = 0,
    SET   = !RESET,
    LOW   = RESET,
    HIGH  = SET,
} FlagStatus, ITStatus;

typedef enum
{
    DISABLE = 0,
    ENABLE  = !DISABLE
} FunctionalState;

typedef enum
{
    ERROR   = 0,
    SUCCESS = !ERROR
} ErrorStatus;

#define IS_FUNCTIONAL_STATE(STATE)              (((STATE) == DISABLE) || ((STATE) == ENABLE))

#define HAL_MAX_DELAY                           0xFFFFFFFFU

#define HAL_IS_BIT_SET(REG, BIT)                (((REG) & (BIT)) != 0U)
#define HAL_IS_BIT_CLR(REG, BIT)                (((REG) & (BIT)) == 0U)

#define SET_BIT(REG, BIT)                       ((REG) |= (BIT))

#define CLEAR_BIT(REG, BIT)                     ((REG) &= ~(BIT))

#define READ_BIT(REG, BIT)                      ((REG) & (BIT))

#define CLEAR_REG(REG)                          ((REG) = (0x0))

#define WRITE_REG(REG, VAL)                     ((REG) = (VAL))

#define READ_REG(REG)                           ((REG))

#define MODIFY_REG(REG, CLEARMASK, SETVALUE)    WRITE_REG((REG), ((READ_REG(REG) & (~(CLEARMASK))) | (SETVALUE)))

#define WRITE_REG_MASK(REG, MASK, VALUE)        WRITE_REG((REG), ((READ_REG(REG) & (~(MASK))) | ((VALUE) & (MASK))))

#define CLEAR_WPBIT(REG, CLEARMASK, WPKEY)      WRITE_REG((REG), ((READ_REG(REG)) & (~(CLEARMASK))) | WPKEY)

#define POSITION_VAL(VAL)       (__CLZ(__RBIT(VAL)))

#define UNUSED(X)               (void)X      /* To avoid gcc/g++ warnings */

#define __HAL_LINKDMA(__HANDLE__, __DMA_FIELD__, __DMA_HANDLE__)    \
            do {                                                    \
                (__HANDLE__)->__DMA_FIELD__ = &(__DMA_HANDLE__);    \
            } while(0U)

#define ALIGNED_4_ROUNDUP(x)                      (((x) + 0x3) & ~0x3)


/** @brief Reset the Handle's State field.
 * @param __HANDLE__: specifies the Peripheral Handle.
 * @note  This macro can be used for the following purpose:
 *          - When the Handle is declared as local variable; before passing it as parameter
 *            to HAL_PPP_Init() for the first time, it is mandatory to use this macro
 *            to set to 0 the Handle's "State" field.
 *            Otherwise, "State" field may have any random value and the first time the function
 *            HAL_PPP_Init() is called, the low level hardware initialization will be missed
 *            (i.e. HAL_PPP_MspInit() will not be executed).
 *          - When there is a need to reconfigure the low level hardware: instead of calling
 *            HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
 *            In this later function, when the Handle's "State" field is set to 0, it will execute the function
 *            HAL_PPP_MspInit() which will reconfigure the low level hardware.
 * @retval None
 */
#define __HAL_RESET_HANDLE_STATE(__HANDLE__)    ((__HANDLE__)->State = 0U)

#if defined(USE_RTOS) && (USE_RTOS == 1U)
/* Reserved for future use */
#error "USE_RTOS should be 0 in the current HAL release"
#else
#define __HAL_LOCK(__HANDLE__)                         \
            do{                                        \
                if((__HANDLE__)->Lock == HAL_LOCKED)   \
                {                                      \
                   return HAL_BUSY;                    \
                }                                      \
                else                                   \
                {                                      \
                   (__HANDLE__)->Lock = HAL_LOCKED;    \
                }                                      \
            }while (0U)

#define __HAL_UNLOCK(__HANDLE__)                      \
            do{                                       \
                (__HANDLE__)->Lock = HAL_UNLOCKED;    \
            }while (0U)

#endif /* USE_RTOS */

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
#ifndef __weak
#define __weak          __attribute__((weak))
#endif
#ifndef __packed
#define __packed        __attribute__((packed))
#endif
#elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */
#ifndef __weak
#define __weak          __attribute__((weak))
#endif /* __weak */
#ifndef __packed
#define __packed        __attribute__((__packed__))
#endif /* __packed */
#endif /* __GNUC__ */


/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif
#ifndef __ALIGN_END
#define __ALIGN_END     __attribute__ ((aligned (4)))
#endif
#elif defined(__GNUC__) && !defined (__CC_ARM) /* GNU Compiler */
#ifndef __ALIGN_END
#define __ALIGN_END     __attribute__ ((aligned (4)))
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif /* __ALIGN_BEGIN */
#else
#ifndef __ALIGN_END
#define __ALIGN_END
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#if defined(__CC_ARM)      /* ARM Compiler V5*/
#define __ALIGN_BEGIN       __align(4)
#elif defined(__ICCARM__)    /* IAR Compiler */
#define __ALIGN_BEGIN
#endif /* __CC_ARM */
#endif /* __ALIGN_BEGIN */
#endif /* __GNUC__ */


/**
 * @brief  __RAM_FUNC definition
 */
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
/* ARM Compiler V4/V5 and V6
   --------------------------
   RAM functions are defined using the toolchain options.
   Functions that are executed in RAM should reside in a separate source module.
   Using the 'Options for File' dialog you can simply change the 'Code / Const'
   area of a module to a memory space in physical RAM.
   Available memory areas are declared in the 'Target' tab of the 'Options for Target'
   dialog.
*/
#define __RAM_FUNC

#elif defined(__ICCARM__)
/* ICCARM Compiler
   ---------------
   RAM functions are defined using a specific toolchain keyword "__ramfunc".
*/
#define __RAM_FUNC  __ramfunc

#elif defined(__GNUC__)
/* GNU Compiler
   ------------
  RAM functions are defined using a specific toolchain attribute
   "__attribute__((section(".RamFunc")))".
*/
#define __RAM_FUNC  __attribute__((section(".RamFunc")))

#endif

/**
 * @brief  __NOINLINE definition
 */
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined(__GNUC__)
/* ARM V4/V5 and V6 & GNU Compiler
   -------------------------------
*/
#define __NOINLINE      __attribute__ ( (noinline) )

#elif defined ( __ICCARM__ )
/* ICCARM Compiler
   ---------------
*/
#define __NOINLINE      _Pragma("optimize = no_inline")

#endif

#ifndef __used
    #define __used      __attribute__((used))
#endif  /* __used */


#ifdef __cplusplus
}
#endif

#endif /* ___ZB32L03x_HAL_DEF */


